/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ngramassigment.calculate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import ngramassigment.Config;
import ngramassigment.data.ResultDataProbability;
import ngramassigment.database.DatabaseManager;
import ngramassigment.fileprocess.ProcessSeparate;

/**
 *
 * @author Tran
 */
public class CalculateProbabilityOfSentence {

    private HashMap<String, Integer> hmId = new HashMap<String, Integer>();
    private static CalculateProbabilityOfSentence instance = null;

    public static CalculateProbabilityOfSentence getInstance() {
        if (instance == null) {
            instance = new CalculateProbabilityOfSentence();
        }
        return instance;
    }

    public CalculateProbabilityOfSentence() {
        hmId = DatabaseManager.getInstance().selectAllDataOfVocabulary();
    }

    public List<String> getListWordOfSentence(String sentence) {
        sentence = insertPreAtom(sentence);
        sentence = separateSentence(sentence);
        return getAllWordOfSentence(sentence);
    }
    public List<ResultDataProbability> calculateProbOfSentences(List<String> lsAllWord, int typeGram) {
        
        List<ResultDataProbability> lsProbWord = calculateProbOfListWord(lsAllWord, typeGram);
        return lsProbWord;
    }

    private List<ResultDataProbability> calculateProbOfListWord(List<String> lsAllWord, int typeGram) {
        List<ResultDataProbability> lsProbWord = new ArrayList<ResultDataProbability>();
        int initStart = 1;
        int start = typeGram - 1;        
        for (int i = initStart; i < lsAllWord.size(); i++) {
            List<String> lsWordForCal = new ArrayList<String>();
            int startJ = i - (typeGram - 1);
            if  (i < start) {
                startJ = 0;
            }
            for (int j = startJ; j <= i; j++) {
                lsWordForCal.add(lsAllWord.get(j));
            }
            lsProbWord.add(calculateProbNGram(lsWordForCal));
        }
        return lsProbWord;
    }

    private String insertPreAtom(String sentence) {
        return (Config.SYMBOY_START.concat(sentence)).concat(Config.SYMBOY_END);
    }

    private String separateSentence(String sentence) {
        return ProcessSeparate.getInstance().processOneLineFileInit(sentence, "");
    }

    private List<String> getAllWordOfSentence(String sentences) {
        String[] lsWord = sentences.trim().split("\\s+");
        List<String> lsWordFilter = new ArrayList<String>();

        for (int i = 0; i < lsWord.length; i++) {
            if (lsWord[i].trim().length() >= 1) {
                lsWordFilter.add(lsWord[i].trim().toUpperCase());
            }
        }
        return lsWordFilter;
    }

    private ResultDataProbability calculateProbNGram(List<String> lsWordForCal ) {
        int typeGram = lsWordForCal.size();
        try {
            double calculateIndexAll = 0;
            for (int j = 0; j < typeGram; j++) {
                calculateIndexAll += ((double) hmId.get(lsWordForCal.get(j))) * ((double) Math.pow(Config.MAX_WORD, typeGram - j - 1));
            }
            int countW2W1 = DatabaseManager.getInstance().countOfNGramFull(calculateIndexAll, typeGram);
            int countW1 = DatabaseManager.getInstance().countOfNGramAPart(calculateIndexAll, hmId.get(lsWordForCal.get(typeGram - 1)), typeGram);
            return new ResultDataProbability(countW2W1, countW1);
        } catch (Exception e) {
            return new ResultDataProbability(0, 0);
        }
    }
}
